﻿using AutoMapper;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json;
using Opc.Ua;
using SHRIS.MIS.Common.Util.Extension;
using SHRIS.MIS.Entity.ScadaData;
using SHRIS.MIS.IService.APIExternal;
using SHRIS.MIS.Model.Param.APIExternal;
using SHRIS.MIS.Model.Result.ShellManage;
using SHRIS.MIS.Service.LinePlantService;
using SHRIS.MIS.Web.Controllers;
using SHRIS.MIS.Web.Filter;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace SHRIS.MIS.Web.Areas.ShellManage.Controllers
{
    [Area("ShellManage")]
    public class ShellBasicController : BaseController
    {
        #region 服务注入
        private readonly IMapper _mapper;
        private LinePlantService _linePlantService;
        private IOpcDataSourceService _opcDataSourceService;
        public ShellBasicController(IMapper mapper, LinePlantService linePlantService, IOpcDataSourceService opcDataSourceService)
        {
            _mapper = mapper;
            _linePlantService = linePlantService;
            _opcDataSourceService = opcDataSourceService;
        }
        #endregion

        #region 视图功能

        [AuthorizeFilter("firstLine:preview")]
        public IActionResult FirstShell()
        {
            return View();
        }

        [AuthorizeFilter("secondLine:preview")]
        public IActionResult SecondShell()
        {
            return View();
        }

        #endregion

        #region API服务
        /// <summary>
        /// 初始化数据
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetInitData()
        {
            return Json(getSendData());
        }

        /// <summary>
        /// 获取跟踪数据
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetTrackData()
        {
            return Json(getSendData());
        }

        /// <summary>
        /// 写一个bool类型的值
        /// </summary>
        /// <param name="deviceCode"></param>
        /// <param name="dataName"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> WriteValue(string deviceCode, string dataName, bool value)
        {
            bool result = false;
            string msg = "";
            // 根据deviceCode 和 dataName找出 SourceAddress
            var opcDataSource = await _opcDataSourceService.GetOpcDataSourceByDeviceCodeAndDataName(deviceCode, dataName);
            try
            {
                foreach (var dataSource in opcDataSource)
                {
                    result = _linePlantService.WriteValue<bool>(dataSource, value);
                }
            }
            catch(Exception ex)
            {
                msg = ex.Message;
            }

            var obj = new
            {
                result = result,
                msg = msg
            };
            return Json(obj);
        }

        /// <summary>
        /// 手动搬运工件设置
        /// </summary>
        /// <param name="from"></param>
        /// <param name="to"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> TransferMateril(short from, short to)
        {
            bool result = false;
            string msg = "";
            var fromDataSource = await _opcDataSourceService.GetOpcDataSourceByDeviceCodeAndDataName("MainPlcControl", "Transfer_from");
            var toDataSource = await _opcDataSourceService.GetOpcDataSourceByDeviceCodeAndDataName("MainPlcControl", "Transfer_to");
            var enterDataSource = await _opcDataSourceService.GetOpcDataSourceByDeviceCodeAndDataName("MainPlcControl", "Transfer_enter");
            try
            {
                foreach (var from_d in fromDataSource)
                {
                    // 写 from
                    result = _linePlantService.WriteValue<short>(from_d, from);
                    if (result)
                    {
                        foreach (var to_d in toDataSource)
                        {
                            // 写 to
                            result = _linePlantService.WriteValue<short>(to_d, to);
                        }
                        if (result)
                        {
                            foreach (var enter_d in enterDataSource)
                            {
                                // 写 确认
                                result = _linePlantService.WriteValue<bool>(enter_d, true);
                            }
                        }
                    }
                }
            }
            catch (Exception e)
            {
                result = false;
                msg = e.Message;
            }

            var obj = new
            {
                result = result,
                msg = msg
            };
            return Json(obj);

        }

        /// <summary>
        /// 手动搬运工件结束，置false
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> TransferMaterilEnd()
        {
            bool result = false;
            string msg = "";
            var enterDataSource = await _opcDataSourceService.GetOpcDataSourceByDeviceCodeAndDataName("MainPlcControl", "Transfer_enter");
            try
            {
                foreach (var enter_d in enterDataSource)
                {
                    // 写 确认
                    result = _linePlantService.WriteValue<bool>(enter_d, false);
                }
            }
            catch (Exception e)
            {
                result = false;
                msg = e.Message;
            }

            var obj = new
            {
                result = result,
                msg = msg
            };
            return Json(obj);
        }

        /// <summary>
        /// 设置孔深测量次数
        /// </summary>
        /// <param name="count"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> SetMeasureCount(short count)
        {
            //short _count = short.Parse(count);
            bool result = false;
            Guid guid = new Guid("469EE4F2-9A66-4914-BC7E-A060C48A2570");
            result = _linePlantService.WriteValue<short>(guid, "ns=2;s=Xibei01.MainPlcControl.HoleDepthMeasure.ProductionData.CountSet", count);
            var obj = new
            {
                result = result
            };
            return Json(obj);
        }

        /// <summary>
        /// 获取连接状态
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> GetConnectStatus()
        {
            IEnumerable<OpcServerStatusDto> status = _linePlantService.GetOpcServerStatus();
            OpcServerStatusDto result = null;
            foreach(OpcServerStatusDto d in status)
            {
                Guid guid = new Guid("469EE4F2-9A66-4914-BC7E-A060C48A2570");
                if (d.server.Id == guid)
                {
                    result = d;
                }

            }
            return Json(new { result = result });
        }

        /// <summary>
        /// 设置料车数量
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> SetCarNumber(string carCode,short num)
        {
            num = short.Parse(num.ToString());
            bool result = false;
            string msg = "";
            Guid serverId = new Guid("469EE4F2-9A66-4914-BC7E-A060C48A2570");
            string tag = null;
            switch (carCode)
            {
                case "上料车01":
                    {
                        tag = "ns=2;s=Xibei01.MainPlcControl.LoadCar01.ProductionData.SetNum";
                        break;
                    }
                case "上料车02":
                    {
                        tag = "ns=2;s=Xibei01.MainPlcControl.LoadCar02.ProductionData.SetNum";
                        break;
                    }
                case "下料车01":
                    {
                        tag = "ns=2;s=Xibei01.MainPlcControl.DownCar01.ProductionData.SetNum";
                        break;
                    }
                case "下料车02":
                    {
                        tag = "ns=2;s=Xibei01.MainPlcControl.DownCar02.ProductionData.SetNum";
                        break;
                    }
                case "NG料车":
                    {
                        tag = "ns=2;s=Xibei01.MainPlcControl.NgCar.ProductionData.SetNum";
                        break;
                    }
            }
            try
            {
                if (tag == null)
                {
                    msg = "错误的别名！";
                }
                else
                {
                    result = _linePlantService.WriteValue<short>(serverId, tag, num);
                }
            }
            catch (Exception ex)
            {
                msg = ex.Message;
            }
            var obj = new
            {
                result = result,
                msg = msg
            };
            return Json(obj);
        }

        /// <summary>
        /// 开始扫码 或 开始打标 指令
        /// </summary>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> StartCodeOrMark(string command,string value)
        {
            bool result = false;
            string msg = "";
            try
            {
                if (command == "StartScanCode")
                {
                    // 开始扫码
                }
                else
                {
                    // 开始打标
                }
            }
            catch(Exception ex)
            {
                msg = ex.Message;
            }
            var obj = new
            {
                result=result,
                msg=msg
            };
            return Json(obj);
        }
        #endregion

        #region 辅助方法

        public Object getSendData()
        {
            // 总控PLC状态
            var mainPlcStatus = new
            {
                OrderControlMode = _linePlantService.OrderControlMode,
                ManualStatus = _linePlantService.ManualStatus,
                AutoStatus = _linePlantService.AutoStatus,
                FirstpieceStatus = _linePlantService.FirstpieceStatus,
                AutoReadyStatus = _linePlantService.AutoReadyStatus,
                AutoRunStatus = _linePlantService.AutoRunStatus,
                AutoStopStatus = _linePlantService.AutoStopStatus,
                AllRestartStatus = _linePlantService.AllRestartStatus,
                SuspendStatus = _linePlantService.SuspendStatus,
                BypassStatus_01 = _linePlantService.BypassStatus_01,
                BypassStatus_02 = _linePlantService.BypassStatus_02,
                BypassStatus_03 = _linePlantService.BypassStatus_03,
                EMO_01 = _linePlantService.EMO_01,
                EMO_02 = _linePlantService.EMO_02,
                EMO_03 = _linePlantService.EMO_03,
                Ready_01 = _linePlantService.Ready_01,
                Ready_02 = _linePlantService.Ready_02,
                Ready_03 = _linePlantService.Ready_03,
                End_01 = _linePlantService.End_01,
                End_02 = _linePlantService.End_02,
                End_03 = _linePlantService.End_03,
                HasWorkpiece_01 = _linePlantService.HasWorkpiece_01,
                HasWorkpiece_02 = _linePlantService.HasWorkpiece_02,
                HasWorkpiece_03 = _linePlantService.HasWorkpiece_03,
                WorkpieceSource_01 = _linePlantService.WorkpieceSource_01,
                WorkpieceSource_02 = _linePlantService.WorkpieceSource_02,
                WorkpieceSource_03 = _linePlantService.WorkpieceSource_03,
                DayOffStatus = _linePlantService.DayOffStatus
            };

            // 孔深测量数据
            var holeDepthMeasure = new
            {
                BypassStatus = _linePlantService._02_BypassStatus,
                EMO = _linePlantService._02_EMO,
                Ready = _linePlantService._02_Ready,
                End = _linePlantService._02_End,
                HasWorkpiece = _linePlantService._02_HasWorkpiece,
                RealCount = _linePlantService._02_RealCount,
                WorkpieceSource = _linePlantService._02_WorkpieceSource,
                CountSet = _linePlantService._02_CountSet,
            };

            // 缓存台1 2 3 4 5 6
            var cacheStation1 = new
            {
                HasWorkpiece = _linePlantService._10_HasWorkpiece_1,
                WorkpieceSource = _linePlantService._10_WorkpieceSource_1
            };
            var cacheStation2 = new
            {
                HasWorkpiece = _linePlantService._10_HasWorkpiece_2,
                WorkpieceSource = _linePlantService._10_WorkpieceSource_2
            };
            var cacheStation3 = new
            {
                HasWorkpiece = _linePlantService._10_HasWorkpiece_3,
                WorkpieceSource = _linePlantService._10_WorkpieceSource_3
            };
            var cacheStation4 = new
            {
                HasWorkpiece = _linePlantService._10_HasWorkpiece_4,
                WorkpieceSource = _linePlantService._10_WorkpieceSource_4
            };
            var cacheStation5 = new
            {
                HasWorkpiece = _linePlantService._10_HasWorkpiece_5,
                WorkpieceSource = _linePlantService._10_WorkpieceSource_5
            };
            var cacheStation6 = new
            {
                HasWorkpiece = _linePlantService._10_HasWorkpiece_6,
                WorkpieceSource = _linePlantService._10_WorkpieceSource_6
            };

            // 地轨机器人
            var downCar1 = new
            {
                AtStation = _linePlantService._08_AtStation_D1,
                Full = _linePlantService._08_Full_D1,
                WorkpieceNum = _linePlantService._08_WorkpieceNum_D1
            };
            var downCar2 = new
            {
                AtStation = _linePlantService._08_AtStation_D2,
                Full = _linePlantService._08_Full_D2,
                WorkpieceNum = _linePlantService._08_WorkpieceNum_D2
            };
            var loadCar1 = new
            {
                AtStation = _linePlantService._08_AtStation_L1,
                Empty = _linePlantService._08_Empty_L1,
                WorkpieceNum = _linePlantService._08_WorkpieceNum_L1
            };
            var loadCar2 = new
            {
                AtStation = _linePlantService._08_AtStation_L2,
                Empty = _linePlantService._08_Empty_L2,
                WorkpieceNum = _linePlantService._08_WorkpieceNum_L2
            };
            var NGCar = new
            {
                AtStation = _linePlantService._08_AtStation_NG,
                Full = _linePlantService._08_Full_NG,
                WorkpieceNum = _linePlantService._08_WorkpieceNum_NG
            };
            // 扫码器
            var scanner = new
            {
                StartScanCodeStatus = _linePlantService._13_StartScanCodeStatus,
                AgainStatus=_linePlantService._13_AgainStatus,
                PassStatus=_linePlantService._13_PassStatus,
                ScanCodeBypassStatus=_linePlantService._13_ScanCodeBypassStatus,
                ScanCodeCom=_linePlantService._13_ScanCodeCom,
                ScanCodeContent=_linePlantService._13_ScanCodeContent,
                ScanCodeContent_Enter=_linePlantService._13_ScanCodeContent_Enter,
                AutoPassStatus=_linePlantService._13_AutoPassStatus,
                AutoPassContent=_linePlantService._13_AutoPassContent
            };
            // 激光打码
            var laserMark = new
            {
                InitStatus = _linePlantService._06_InitStatus,
                StartMarkStatus = _linePlantService._06_StartMarkStatus,
                CodeBypassStatus = _linePlantService._06_CodeBypassStatus,
                EMO = _linePlantService._06_EMO,
                Ready = _linePlantService._06_Ready,
                End = _linePlantService._06_End,
                HasWorkpiece=_linePlantService._06_HasWorkpiece,
                Com=_linePlantService._06_Com,
                InitSuccess=_linePlantService._06_InitSuccess,
                MarkComplete=_linePlantService._06_MarkComplete,
                WorkpieceSource=_linePlantService._06_WorkpieceSource,
                MarkContent_Enter=_linePlantService._06_MarkContent_Enter,
                Result=_linePlantService._06_Result
            };
            // 机械手
            var manipulator = new
            {
                RestartStatus=_linePlantService._09_RestartStatus,
                EMO=_linePlantService._09_EMO,
                Ready=_linePlantService._09_Ready,
                HasWorkpiece=_linePlantService._09_HasWorkpiece,
                WorkpieceSource=_linePlantService._09_WorkpieceSource,
                Grab01=_linePlantService._09_Grab01,
                Grab02=_linePlantService._09_Grab02,
                Put01=_linePlantService._09_Put01,
                Put02=_linePlantService._09_Put02,
                Position=_linePlantService._09_Position
            };

            // 清洗机
            var WashMachine = new
            {
                BypassStatus=_linePlantService._01_BypassStatus,
                EMO=_linePlantService._01_EMO,
                Ready=_linePlantService._01_Ready,
                End=_linePlantService._01_End,
                WorkpieceSource=_linePlantService._01_WorkpieceSource
            };

            // 三坐标测量
            var ThreeCoordinatesMeasure = new
            {
                BypassStatus=_linePlantService._11_BypassStatus,
                Ready=_linePlantService._11_Ready,
                End=_linePlantService._11_End,
                HasWorkpiece=_linePlantService._11_HasWorkpiece,
                WorkpieceSource=_linePlantService._11_WorkpieceSource
            };

            var obj = new
            {
                mainPlcStatus = mainPlcStatus,
                holeDepthMeasure = holeDepthMeasure,
                cacheStation1 = cacheStation1,
                cacheStation2 = cacheStation2,
                cacheStation3 = cacheStation3,
                cacheStation4 = cacheStation4,
                cacheStation5 = cacheStation5,
                cacheStation6 = cacheStation6,
                downCar1= downCar1,
                downCar2= downCar2,
                loadCar1= loadCar1,
                loadCar2= loadCar2,
                NGCar= NGCar,
                scanner= scanner,
                laserMark= laserMark,
                manipulator= manipulator,
                WashMachine= WashMachine,
                ThreeCoordinatesMeasure= ThreeCoordinatesMeasure
            };
            return obj;
        }

        /// <summary>
        /// 将HTTP请求对象转换为便于操作的JSON对象
        /// </summary>
        /// <param name="data">req对象</param>
        /// <returns>JSON对象</returns>
        public IDictionary<string, object> ChangeJsonObject(object data)
        {
            var jsonobj = JsonConvert.SerializeObject(data);
            var result = JsonConvert.DeserializeObject<IDictionary<string, object>>(jsonobj);
            return result;
        }
        #endregion
    }
}
